package org.zoomdev.zoom.common.utils;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.zoomdev.zoom.common.exceptions.ZoomException;
import org.zoomdev.zoom.common.io.Io;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.URL;
import java.net.URLDecoder;
import java.util.Collection;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;


public final class PathUtils {

    private static final Logger log = LoggerFactory.getLogger(PathUtils.class);
    public static boolean isInProject = false;
    public static boolean isInWebInf = false;
    public static boolean isInJar = false;
    /**
     *
     */
    private static String rootPath;

    /**
     * 获取程序根目录
     * 对于网站  /WEB-INF/classes
     * 对于jar  jar所在路径
     * 对于class class所在路径
     *
     * @return
     */
    //jar 文件路径
    private static String jarPath;

    /**
     * 获取网站根目录
     *
     * @return
     */
    public static String getRootPath() {
        if (rootPath == null) {
            synchronized (PathUtils.class) {
                if (rootPath == null) {
                    try {
                        URL url = PathUtils.class.getClassLoader().getResource("");
                        //全部都指向target/classes 默认目录
                        String path;
                        if (url == null) {
                            //运行在jar
                            File root = new File("");
                            String jarPath = PathUtils.class.getProtectionDomain().getCodeSource().getLocation().getPath();
                            try {
                                PathUtils.jarPath = URLDecoder.decode(jarPath, "utf-8");
                            } catch (Exception e) {

                            }
                            isInJar = true;
                            path = root.getCanonicalPath();
                        } else {
                            path = url.toURI().getPath();
                            //windows
                        }
                        path = path.replace("\\", "/");
                        if (!path.endsWith("/")) {
                            path = path + "/";
                        }

                        if (!isInJar) {
                            if (path.endsWith("target/classes/")) {
                                isInProject = true;
                                path = path.substring(0, path.length() - "target/classes/".length());
                            } else if (path.endsWith("WEB-INF/classes/")) {
                                isInWebInf = true;
                                path = path.substring(0, path.length() - "WEB-INF/classes/".length());
                            }
                        }


                        if (File.separator.equals("\\")) {
                            //path = path.replace("/","\\");
                            if (path.charAt(2) == ':') {
                                path = path.charAt(1) + "://" + path.substring(4);
                            }
                        }

                        if (!path.endsWith(File.separator)) {
                            path = path + File.separator;
                        }

                        rootPath = path;
                    } catch (Exception e) {
                        throw new RuntimeException("获取根目录失败", e);
                    }
                }
            }
        }
        return rootPath;

    }

    public static String getJarPath() {
        getRootPath();
        return jarPath;
    }

    /**
     * @param name
     * @return
     */
    public static File getWebINFPath(String name) {
        String root = PathUtils.getRootPath();
        if (isInProject) {
            return new File(root + "src" + File.separator + "main" + File.separator + "webapp" + File.separator + "WEB-INF" + File.separator + name);
        } else {
            return new File(root + "WEB-INF" + File.separator + name);
        }
    }


    /**
     * 获取运行环境中涉及到的所有需要进行扫描的文件
     *
     * @return
     */
    public static Collection<String> getSources() {
        String root = getRootPath();
        Set<String> result = new HashSet<>();
        if (isInJar) {
            log.info(String.format("========程序运行在jar中,增加jar路径[%s],当前根目录[%s]==========", PathUtils.jarPath, root));
            File jar = new File(PathUtils.jarPath);
            if (!jar.exists()) {
                throw new ZoomException("jar不存在:" + PathUtils.jarPath);
            }
            result.add(jar.getAbsolutePath());
            InputStream is = PathUtils.class.getClassLoader().getResourceAsStream("META-INF/MANIFEST.MF");
            if (is != null) {
                try {
                    byte[] bytes = Io.readBytes(is);
                    String content = new String(bytes);

                    String reg = "([a-zA-Z-0-9]+): ";

                    Pattern p = Pattern.compile(reg);

                    Matcher matcher = p.matcher(content);

                    boolean find = false;
                    int start = 0;
                    int end = content.length();
                    while (matcher.find()) {
                        if ("Class-Path".equals(matcher.group(1))) {
                            start = matcher.start() + "Class-Path".length() + 1;
                            find = true;
                            continue;
                        }

                        if (find) {
                            end = matcher.start();
                            break;
                        }
                    }

                    String path = content.substring(start, end);
                    String[] parts = path.split("\r\n");
                    StringBuilder sb = new StringBuilder();
                    for (String part : parts) {
                        sb.append(part.substring(1));
                    }
                    path = sb.toString();
                    String[] libs = path.split(" ");
                    for (String lib : libs) {
                        File libFile = new File(root, lib);
                        if (libFile.exists()) {
                            if (log.isDebugEnabled()) {
                                log.debug("增加jar文件" + libFile.getAbsolutePath());
                            }
                            result.add(libFile.getAbsolutePath());
                        }
                    }

                } catch (IOException e) {

                }

            }


        } else {
            Enumeration<URL> enumeration = null;
            try {
                enumeration = PathUtils.class.getClassLoader().getResources("");
                while (enumeration.hasMoreElements()) {
                    URL url = enumeration.nextElement();
                    String folder = null;
                    try {
                        folder = URLDecoder.decode(url.getFile(), "UTF-8");
                    } catch (UnsupportedEncodingException e) {
                        continue;
                    }
                    File file = new File(folder);
                    if (!file.isDirectory()) {
                        continue;
                    }
                    result.add(file.getAbsolutePath());
                }
            } catch (IOException e) {

            }
            File lib = PathUtils.getWebINFPath("lib");
            if (lib.exists()) {
                result.add(lib.getAbsolutePath());
            }
        }

        String[] parts = Classes.getClassPaths();
        for (String part : parts) {
            File file = new File(part);
            if (file.exists()) {
                result.add(file.getAbsolutePath());
            }
        }

        return result;
    }

}
